home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Applications
/
Python 1.3.3
/
Python 133 SRC
/
Extensions
/
img
/
imgopmodule.c
< prev
next >
Wrap
Text File
|
1995-12-21
|
10KB
|
308 lines
/***********************************************************
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
******************************************************************/
#include "Python.h"
#include "import.h"
/*
** An Order-8 ordered dithering matrix. Taken from netpbm, which in
** turn has it from "Digital Halftoning" by Robert Ulichney, MIT
** Press, ISBN 0-262-21009-6.
*/
static int dither8[16][16] = {
1,235, 59,219, 15,231, 55,215, 2,232, 56,216, 12,228, 52,212,
129, 65,187,123,143, 79,183,119,130, 66,184,120,140, 76,180,116,
33,193, 17,251, 47,207, 31,247, 34,194, 18,248, 44,204, 28,244,
161, 97,145, 81,175,111,159, 95,162, 98,146, 82,172,108,156, 92,
9,225, 49,209, 5,239, 63,223, 10,226, 50,210, 6,236, 60,220,
137, 73,177,113,133, 69,191,127,138, 74,178,114,134, 70,188,124,
41,201, 25,241, 37,197, 21,255, 42,202, 26,242, 38,198, 22,252,
169,105,153, 89,165,101,149, 85,170,106,154, 90,166,102,150, 86,
3,233, 57,217, 13,229, 53,213, 0,234, 58,218, 14,230, 54,214,
131, 67,185,121,141, 77,181,117,128, 64,186,122,142, 78,182,118,
35,195, 19,249, 45,205, 29,245, 32,192, 16,250, 46,206, 30,246,
163, 99,147, 83,173,109,157, 93,160, 96,144, 80,174,110,158, 94,
11,227, 51,211, 7,237, 61,221, 8,224, 48,208, 4,238, 62,222,
139, 75,179,115,135, 71,189,125,136, 72,176,112,132, 68,190,126,
43,203, 27,243, 39,199, 23,253, 40,200, 24,240, 36,196, 20,254,
171,107,155, 91,167,103,151, 87,168,104,152, 88,164,100,148, 84 };
static PyObject *errobject;
static PyObject *format_grey, *format_xgrey, *format_bitmap;
/*
** Get the relevant info from a format object:
** pixel size and alignment and bitpositions and masks for
** each component.
*/
static int
getfmtinfo(fmt, size, align, mr, mg, mb, sr, sg, sb)
PyObject *fmt;
int *size, *align, *mr, *mg, *mb, *sr, *sg, *sb;
{
PyObject *dict, *value;
int ma, sa;
if ( (dict=PyObject_GetAttrString(fmt, "descr")) == NULL )
return 0;
if ( (value=PyDict_GetItemString(dict, "size")) == NULL )
return 0;
if ( (*size=PyInt_AsLong(value)) == -1 )
return 0;
if ( *size != 8 && *size != 16 && *size != 32 )
return 0;
*size /= 8;
if ( (value=PyDict_GetItemString(dict, "align")) == NULL )
return 0;
if ( (*align=PyInt_AsLong(value)) == -1 )
return 0;
if ( *align != 8 && *align != 16 && *align != 32 )
return 0;
*align /= 8;
if ( (value=PyDict_GetItemString(dict, "comp")) == NULL )
return 0;
*mr = *mg = *mb = *sr = *sg = *sb = ma = sa = 0;
if ( !PyArg_ParseTuple(value, "(ii)|(ii)(ii)(ii)",
sr, mr, sg, mg, sb, mb, &sa, &ma) )
return 0;
*mr = (1<<*mr) - 1;
*mg = (1<<*mg) - 1;
*mb = (1<<*mb) - 1;
Py_DECREF(dict);
return 1;
}
static char doc_shuffle[] =
"Re-arrange component bits in pixels.\n"
"Args: (data, width, height, source_format, result_format)\n"
"Returns: string containing shuffled pixel data";
static PyObject *
imo_shuffle(self, args)
PyObject *self;
PyObject *args;
{
PyObject *srcfmt, *dstfmt;
unsigned char *srcp8, *dstp8;
unsigned short *srcp16, *dstp16;
unsigned long *srcp32, *dstp32;
unsigned long srcpixel, dstpixel, comp;
int srcalign, dstalign;
int srcsize, dstsize;
int smr, smg, smb, ssr, ssg, ssb, dmr, dmg, dmb, dsr, dsg, dsb;
PyObject *rv;
int w, rowlen, h, size, x, y;
if (!PyArg_ParseTuple(args, "s#iiOO", &srcp8, &size, &w, &h,
&srcfmt, &dstfmt))
return NULL;
/*
** Get the relevant info from the format objects, do some argument
** checking and allocate the result buffer.
*/
if (!getfmtinfo(srcfmt, &srcsize, &srcalign, &smr, &smg, &smb,
&ssr, &ssg, &ssb) ||
!getfmtinfo(dstfmt, &dstsize, &dstalign, &dmr, &dmg,
&dmb, &dsr, &dsg, &dsb) ) {
PyErr_SetString(errobject, "Invalid format-object");
return NULL;
}
rowlen = (w*srcsize+srcalign-1) & ~(srcalign-1);
if ( rowlen*h != size ) {
PyErr_SetString(errobject, "Incorrectly sized data");
return NULL;
}
rowlen = (w*dstsize+dstalign-1) & ~(dstalign-1);
if ( (rv=PyString_FromStringAndSize((char *)0, rowlen*h)) == 0 )
return NULL;
dstp8 = (unsigned char *)PyString_AsString(rv);
dstp16 = (unsigned short *)dstp8;
dstp32 = (unsigned long *)dstp8;
srcp16 = (unsigned short *)srcp8;
srcp32 = (unsigned long *)srcp8;
for( y=0; y<h; y++) {
for( x=0; x<w; x++ ) {
/* Get the source pixel into srcpixel */
if ( srcsize==1 ) srcpixel = *srcp8++; else
if ( srcsize==2 ) srcpixel = *srcp16++; else
srcpixel = *srcp32++;
dstpixel = 0;
/* For each existing (and wanted) component,
**grab/scale/insert it
*/
if ( smr && dmr ) {
comp = (srcpixel >> ssr) & smr; /* Get bits */
comp = (comp*dmr)/smr; /* convert magnitude */
dstpixel = dstpixel | (comp<<dsr); /* Insert */
}
if ( smg && dmg ) {
comp = (srcpixel >> ssg) & smg;
comp = (comp*dmg)/smg;
dstpixel = dstpixel | (comp << dsg);
}
if ( smb && dmb ) {
comp = (srcpixel >> ssb) & smb;
comp = (comp*dmb)/smb;
dstpixel = dstpixel | (comp << dsb);
}
/* And put the result in the output buffer,
**in the correct size
*/
if ( dstsize==1 ) *dstp8++ = dstpixel; else
if ( dstsize==2 ) *dstp16++ = dstpixel; else
*dstp32++ = dstpixel;
}
/* Finally, do end-of-row alignment. Note that this code works
** because we have checked that size and align are 1, 2 or 4,
** nothing else.
*/
if ( srcalign > srcsize ) {
if ( srcsize==1 )
while( (long)srcp8 & (srcalign-1) ) srcp8++;
else if ( srcsize==2 )
while( (long)srcp16 & (srcalign-1) ) srcp16++;
else
while( (long)srcp32 & (srcalign-1) ) srcp32++;
}
if ( dstalign > dstsize ) {
if ( dstsize==1 )
while( (long)dstp8 & (dstalign-1) )
*dstp8++ = 0;
else if ( srcsize==2 )
while( (long)dstp16 & (dstalign-1) )
*dstp16++ = 0;
else
while( (long)dstp32 & (dstalign-1) )
*dstp32++ = 0;
}
}
return rv;
}
static char doc_dither[] =
"Dither greyscale to bitmap using an order-8 ordered dither.\n"
"Args: (data, width, height, source_format, result_format)\n"
"Returns: string containing bitmap data";
static PyObject *
imo_dither(self, args)
PyObject *self;
PyObject *args;
{
PyObject *srcfmt, *dstfmt;
PyObject *rv;
unsigned char *srcdata, *dstdata;
int x, y, h, w, rowlen, size;
#define _SRC(x, y) (srcdata[((y)*rowlen)+(x)])
#define _DST(x, y) (dstdata[((y)*w)+(x)])
if ( !PyArg_ParseTuple(args, "s#iiOO", &srcdata, &size, &w, &h,
&srcfmt, &dstfmt) )
return NULL;
if ( (srcfmt != format_xgrey && srcfmt != format_grey) ||
dstfmt != format_bitmap ) {
PyErr_SetString(errobject,
"Only supporting (x)grey to pbmbitmap currently");
return NULL;
}
if (srcfmt == format_grey )
rowlen = (w+3) & ~3;
else
rowlen = w;
if ( size != rowlen*h ) {
PyErr_SetString(errobject, "Incorrect data size");
return NULL;
}
if( (rv=PyString_FromStringAndSize((char *)0, w*h)) == NULL )
return NULL;
dstdata = (unsigned char *)PyString_AsString(rv);
for(y=0; y<w; y++)
for(x=0; x<h; x++)
if ( _SRC(x, y) >= dither8[y&0xf][x&0xf] )
_DST(x, y) = 1;
else
_DST(x, y) = 0;
return rv;
}
/* List of functions defined in the module */
static struct PyMethodDef xxx_module_methods[] = {
{"shuffle", imo_shuffle, 1, doc_shuffle},
{"dither", imo_dither, 1, doc_dither},
{NULL, NULL} /* sentinel */
};
/* Initialization function for the module (*must* be called initimgxxx) */
static char doc_imgop[] = "Various operations on images";
void
initimgop()
{
PyObject *m, *d, *x, *formatmodule, *formatdict;
/* Create the module and add the functions */
m = Py_InitModule("imgop", xxx_module_methods);
/* Add some symbolic constants to the module */
d = PyModule_GetDict(m);
errobject = PyString_FromString("imgop.error");
PyDict_SetItemString(d, "error", errobject);
x = PyString_FromString(doc_imgop);
PyDict_SetItemString(d, "__doc__", x);
/* Get supported formats */
if ((formatmodule = PyImport_ImportModule("imgformat")) == NULL)
Py_FatalError("imgxxx depends on imgformat");
if ((formatdict = PyModule_GetDict(formatmodule)) == NULL)
Py_FatalError("imgformat has no dict");
format_grey = PyDict_GetItemString(formatdict,"grey");
format_xgrey = PyDict_GetItemString(formatdict,"xgrey");
format_bitmap = PyDict_GetItemString(formatdict,"pbmbitmap");
/* Check for errors */
if (PyErr_Occurred())
Py_FatalError("can't initialize module imgop");
}